home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / unix / tracker_4_3.lzh / tracker / audio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-13  |  9.7 KB  |  381 lines

  1. /* audio.c 
  2.     vi:se ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: audio.c,v 4.2 1994/02/04 14:53:03 espie Exp espie $
  6.  * $Log: audio.c,v $
  7.  * Revision 4.2  1994/02/04  14:53:03  espie
  8.  * *** empty log message ***
  9.  *
  10.  * Revision 4.1  1994/01/12  16:10:20  espie
  11.  * Fixed up last minute problems.
  12.  *
  13.  * Revision 4.0  1994/01/11  17:39:36  espie
  14.  * Lots of changes.
  15.  *
  16.  * Revision 1.5  1994/01/09  17:36:22  Espie
  17.  * Generalized open.c.
  18.  *
  19.  * Revision 1.4  1994/01/08  03:55:43  Espie
  20.  * Just new names, provide for better !
  21.  *
  22.  * Revision 1.3  1994/01/05  14:54:09  Espie
  23.  * *** empty log message ***
  24.  *
  25.  * Revision 1.2  1993/12/28  13:54:44  Espie
  26.  * Finally corrected irksome probleme with MAX_PITCH.
  27.  *
  28.  * Revision 1.1  1993/12/26  00:55:53  Espie
  29.  * Initial revision
  30.  *
  31.  * Revision 3.10  1993/12/04  16:12:50  espie
  32.  * First changes to augment the number of channels.
  33.  *
  34.  * Revision 3.9  1993/11/17  15:30:16  espie
  35.  * Added one level of abstraction. Look through player.c for the
  36.  * old high-level functions.
  37.  *
  38.  * Revision 3.8  1993/08/04  11:34:33  espie
  39.  * *** empty log message ***
  40.  *
  41.  * Revision 3.7  1993/07/18  10:39:44  espie
  42.  * Cleaned up some code.
  43.  *
  44.  * Revision 3.6  1992/11/27  10:29:00  espie
  45.  * General cleanup
  46.  *
  47.  * Revision 3.5  1992/11/24  10:51:19  espie
  48.  * Optimized output and fixed up some details.
  49.  * Unrolled code for oversample = 1 to be more efficient at
  50.  * higher frequency (since a high frequency is better than
  51.  * a higher oversample).
  52.  *
  53.  * Revision 3.4  1992/11/23  17:18:59  espie
  54.  * *** empty log message ***
  55.  *
  56.  * Revision 3.3  1992/11/23  10:12:23  espie
  57.  * Fixed up BIG bug.
  58.  *
  59.  * Revision 3.2  1992/11/20  14:53:32  espie
  60.  * Added finetune.
  61.  *
  62.  * Revision 3.1  1992/11/19  20:44:47  espie
  63.  * Protracker commands.
  64.  *
  65.  * Revision 3.0  1992/11/18  16:08:05  espie
  66.  * New release.
  67.  *
  68.  * Revision 2.14  1992/11/06  19:31:53  espie
  69.  * Fixed missing parameter type.
  70.  * fix_xxx for better speed.
  71.  * set_volume.
  72.  * Added possibility to get back to MONO for the sgi.
  73.  * Added stereo capabilities to the indigo version.
  74.  * Minor bug: a SAMPLE_FAULT is a minor error,
  75.  * we should first check that there was no other
  76.  * error before setting it.
  77.  * New resample function coming from the player.
  78.  * Added more notes.
  79.  *
  80.  * Revision 2.1  1991/11/17  23:07:58  espie
  81.  * Just computes some frequency-related parameters.
  82.  *
  83.  *
  84.  */
  85.  
  86. #include <math.h>
  87. #ifndef __386BSD__
  88. #include <malloc.h>
  89. #else
  90. #include <stdlib.h>
  91. #endif
  92. #include <stdio.h>
  93.  
  94. #include "defs.h"
  95. #include "song.h"
  96. #include "channel.h"
  97. #include "tags.h"
  98. #include "extern.h"
  99.      
  100. ID("$Id: audio.c,v 4.2 1994/02/04 14:53:03 espie Exp espie $")
  101.  
  102.  
  103. /* DO_NOTHING is also used for the automaton */
  104. #define DO_NOTHING 0
  105. #define PLAY 1
  106. #define REPLAY 2
  107.  
  108. #define MAX_CHANNELS 8
  109.  
  110. LOCAL struct audio_channel
  111.    {
  112.    struct sample_info *samp;
  113.    int mode;
  114.    unsigned long pointer;
  115.    unsigned long step;
  116.    int volume;
  117.    int pitch;
  118.    } chan[MAX_CHANNELS];
  119.  
  120. LOCAL struct sample_info dummy =
  121.    {
  122.    NULL,
  123.    0,
  124.    0,
  125.    0,
  126.    0,
  127.    0,
  128.    0,
  129.    0,
  130.    NULL,
  131.    NULL
  132.    };
  133.  
  134. LOCAL int allocated = 0;
  135.  
  136. struct audio_channel *new_channel_tag_list(prop)
  137. struct tag *prop;
  138.    {
  139.    struct audio_channel *new;
  140.    new = &chan[allocated++];
  141.    new->mode = DO_NOTHING;
  142.    new->pointer = 0;
  143.    new->step = 0;
  144.    new->pitch = 0;
  145.    new->volume = 0;
  146.    new->samp = &dummy;
  147.    return new;
  148.    }
  149.  
  150. void release_audio_channels()
  151.    {
  152.    allocated = 0;
  153.    }
  154.  
  155. /* Have to get some leeway for vibrato (since we don't bound pitch with
  156.  * vibrato). This is conservative.
  157.  */
  158. #define VIB_MAXDEPTH 150
  159.  
  160.  
  161. #define C fix_to_int(ch->pointer)
  162.  
  163. LOCAL unsigned long step_table[REAL_MAX_PITCH + VIB_MAXDEPTH];  
  164.                   /* holds the increment for finding the next sampled
  165.                    * byte at a given pitch (see resample() ).
  166.                    */
  167.  
  168. /* creates a table for converting ``amiga'' pitch
  169.  * to a step rate at a given resampling frequency.
  170.  * For accuracy, we don't use floating point, but
  171.  * instead fixed point ( << ACCURACY).
  172.  * IMPORTANT NOTE: we need to make it fit within 32 bits (long), which
  173.  * must be enough for ACCURACY + log2(max sample length)
  174.  */
  175. LOCAL void create_step_table(oversample, output_fr)
  176. int oversample;     /* we sample oversample i for each byte output */
  177. int output_fr;      /* output frequency */
  178.    {
  179.    double note_fr; /* note frequency (in Hz) */
  180.    double step;
  181.    int pitch;      /* amiga pitch */
  182.  
  183.    step_table[0] = 0;
  184.    for (pitch = 1; pitch < REAL_MAX_PITCH + VIB_MAXDEPTH; pitch++)
  185.       {
  186.       note_fr = AMIGA_CLOCKFREQ / pitch;
  187.          /* int_to_fix(1) is the normalizing factor */
  188.       step = note_fr / output_fr * int_to_fix(1) / oversample;
  189.       step_table[pitch] = (long)step;
  190.       }
  191.    }
  192.          
  193. LOCAL void readjust_pitch()
  194.    {
  195.    int i;
  196.    for (i = 0; i < allocated; i++)
  197.       chan[i].step = step_table[chan[i].pitch];
  198.    }
  199.  
  200. void init_tables(oversample, frequency)
  201. int oversample, frequency;
  202.    {
  203.    create_step_table(oversample, frequency);
  204.    readjust_pitch();
  205.    }
  206.  
  207.  
  208. /* The playing mechanism itself.
  209.  * According to the current channel automaton,
  210.  * we resample the instruments in real time to
  211.  * generate output.
  212.  */
  213. void resample(oversample, number)
  214. int oversample;
  215. int number;
  216.    {
  217.    int i;            /* sample counter */
  218.    int channel;      /* channel counter */
  219.    int sampling;     /* oversample counter */
  220.    int value[NUMBER_TRACKS];
  221.                      /* recombinations of the various data */
  222.    struct audio_channel *ch;
  223.  
  224.       /* safety check: we can't have a segv there, provided
  225.        * chan points to a valid sample.
  226.        * For `empty' samples, what is needed is fix_length = 0
  227.        * and rp_start = NULL
  228.        */
  229.    /* special case optimization */
  230.    if (oversample == 1)
  231.       {
  232.          /* do the resampling, i.e., actually play sounds */
  233.       for (i = 0; i < number; i++) 
  234.          {
  235.          for (channel = 0; channel < allocated; channel++)
  236.             {
  237.             ch = chan + channel;
  238.             switch(ch->mode)
  239.                {
  240.             case DO_NOTHING:
  241.                value[channel] = 0;
  242.                break;
  243.             case PLAY:
  244.                   /* Since we now have fix_length, we can
  245.                    * do that check with improved performance
  246.                    */
  247.                if (ch->pointer < ch->samp->fix_length)
  248.                   {
  249.                   value[channel] = ch->samp->start[C] * ch->volume;
  250.                   ch->pointer += ch->step;
  251.                   break;
  252.                   }
  253.                else
  254.                   {
  255.                   ch->mode = REPLAY;
  256.                   ch->pointer -= ch->samp->fix_length;
  257.                   /* FALLTHRU */
  258.                   }
  259.             case REPLAY:
  260.                      /* is there a replay ? */
  261.                if (!ch->samp->rp_start)
  262.                   {
  263.                   ch->mode = DO_NOTHING;
  264.                   break;
  265.                   }
  266.                while (ch->pointer >= ch->samp->fix_rp_length)
  267.                   ch->pointer -= ch->samp->fix_rp_length;
  268.                value[channel] = ch->samp->rp_start[C] * ch->volume;
  269.                ch->pointer += ch->step;
  270.                break;
  271.                }
  272.             } 
  273.          output_samples(value[0]+value[3], value[1]+value[2]);
  274.          }
  275.       }   
  276.    else
  277.       {
  278.       for (i = 0; i < number; i++) 
  279.          {
  280.          for (channel = 0; channel < allocated; channel++)
  281.             {
  282.             value[channel] = 0;
  283.             for (sampling = 0; sampling < oversample; sampling++)
  284.                {
  285.                ch = chan + channel;
  286.                switch(ch->mode)
  287.                   {
  288.                case DO_NOTHING:
  289.                   break;
  290.                case PLAY:
  291.                      /* Since we now have fix_length, we can
  292.                       * do that check with improved performance
  293.                       */
  294.                   if (ch->pointer < ch->samp->fix_length)
  295.                      {
  296.                      value[channel] += ch->samp->start[C] * ch->volume;
  297.                      ch->pointer += ch->step;
  298.                      break;
  299.                      }
  300.                   else
  301.                      {
  302.                      ch->mode = REPLAY;
  303.                      ch->pointer -= ch->samp->fix_length;
  304.                      /* FALLTHRU */
  305.                      }
  306.                case REPLAY:
  307.                         /* is there a replay ? */
  308.                   if (!ch->samp->rp_start)
  309.                      {
  310.                      ch->mode = DO_NOTHING;
  311.                      break;
  312.                      }
  313.                   while (ch->pointer >= ch->samp->fix_rp_length)
  314.                      ch->pointer -= ch->samp->fix_rp_length;
  315.                   value[channel] += ch->samp->rp_start[C] * ch->volume;
  316.                   ch->pointer += ch->step;
  317.                   break;
  318.                   }
  319.                } 
  320.             }
  321.          output_samples((value[0]+value[3])/oversample, 
  322.             (value[1]+value[2])/oversample);
  323.          }   
  324.       }
  325.  
  326.    flush_buffer();
  327.    }
  328.  
  329.  
  330. /* setting up a given note */
  331.  
  332. void play_note(au, samp, pitch)
  333. struct audio_channel *au;
  334. struct sample_info *samp;
  335. int pitch;
  336.    {
  337.    au->pointer = 0;
  338.    au->pitch = pitch;
  339.    au->step = step_table[pitch];
  340.    if (samp)
  341.       {
  342.       au->samp = samp;
  343.       au->mode = PLAY;
  344.       }
  345.    else
  346.       au->mode = DO_NOTHING;
  347.    }
  348.  
  349. /* changing the current pitch (value
  350.  * may be temporary, and not stored
  351.  * in channel pitch, for instance vibratos.
  352.  */
  353. void set_play_pitch(au, pitch)
  354. struct audio_channel *au;
  355. int pitch;
  356.    {
  357.       /* save current pitch in case we want to change
  358.        * the step table on the run
  359.        */
  360.    au->pitch = pitch;
  361.    au->step = step_table[pitch];
  362.    }
  363.  
  364. /* changing the current volume. You HAVE to get through
  365.  * there so that it will work on EVERY machine.
  366.  */
  367. void set_play_volume(au, volume)
  368. struct audio_channel *au;
  369. int volume;
  370.    {
  371.    au->volume = volume;
  372.    }
  373.  
  374. void set_play_position(au, pos)
  375. struct audio_channel *au;
  376. int pos;
  377.    {
  378.    au->pointer = int_to_fix(pos);
  379.    }
  380.  
  381.